/**************************************************************
 * @file     bsp_key_irq.h
 * @brief    实现按键驱动队列发送消息，基于中断检测按键单击，长按检测
 * @author   Ruilist
 * @date     2025-07-30
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *
 * @par 日志:
 * - V1.0.0 2025-07-30 Ruilist
 *   实现按键驱动队列发送消息
 **************************************************************/

#ifndef __BSP_KEY_IRQ_H__
#define __BSP_KEY_IRQ_H__

//******************************** Includes *********************************//

#include <stdint.h>
#include <stdio.h>

#include "cmsis_os.h"
#include "main.h"

#include "queue.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

#define KEY_Pin       GPIO_PIN_0
#define KEY_GPIO_Port GPIOA

#define FALING_TYPE   0
#define RISING_TYPE   1
#define KEY_CALLBACK  void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )

typedef enum
{
    KEY_OK             = 0,          // Operation completed successfully.
    KEY_ERROR          = 1,          // Run-time error without case matched
    KEY_ERRORTIMEOUT   = 2,          // Operation failed with timeout
    KEY_ERRORRESOURCE  = 3,          // Resource not available.
    KEY_ERRORPARAMETER = 4,          // Parameter error.
    KEY_ERRORNOMEMORY  = 5,          // Out of memory.
    KEY_ERRORISR       = 6,          // Not allowed in ISR context
    KEY_RESERVED       = 0x7FFFFFFF  // Reserved
} key_status_t;

typedef enum
{
    KEY_PRESSED       = 0,  // Operation completed successfully.
    KEY_NOT_PRESSED   = 1,  // Run-time error without case matched
    KEY_SHORT_PRESSED = 2,  // Operation
    KEY_LONG_PRESSED  = 3,  // Operation
} key_press_status_t;

typedef enum
{
    RISING  = 0, /* Operation completed successfully.  */
    FAILING = 1, /* Operation failed                   */
} key_trigger_edge_t;

typedef struct
{
    key_trigger_edge_t edge_type;    /* Operation completed successfully.  */
    uint32_t           trigger_tick; /* Operation completed successfully.  */
} key_press_event_t;

//******************************** Defines **********************************//

//*********************Thread_Func **********************//

extern osThreadId_t         key_TaskHandle;
extern const osThreadAttr_t key_Task_attributes;

//*********************Thread_Func **********************//

//*********************Queue_Handler ********************//

extern QueueHandle_t key_queue;
extern QueueHandle_t inter_key_queue;
//*********************Queue_Handler ********************//

//******************************** Declaring ********************************//

/**
 * @brief   按键任务
 *
 * @param   *argument    任务默认参数
 *
 * @return  空
 *
 */
void key_task_func( void *argument );

/**
 * @brief   按键状态轮询
 *
 * @param   *key_value    用作按键状态传参
 *
 * @return  返回值类型 key_status_t
 *
 */
key_status_t key_scan( key_press_status_t *key_value );

/**
 * @brief   检测按键单击，长按状态
 *
 * @param   *key_value    按键触发状态传参
 * @param   threshold_time    单击检测时间阈值
 *
 * @return  函数状态 key_status_t
 *
 */
key_status_t key_long_short_press( key_press_status_t *key_value, uint32_t threshold_time );

//******************************** Declaring ********************************//

#endif  // End of __BSP_KEY_IRQ_H__
